/**
 * Copyright 2016 JustWayward Team
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.songcha.module_bookreader.ui.view.readview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.opengl.Visibility;
import android.os.Build;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.FrameLayout;
import android.widget.Scroller;
import android.widget.TextView;

import com.songcha.library_business.config.VarConfig;
import com.songcha.library_common.helper.ViewHelper;
import com.songcha.library_common.util.LogUtil;
import com.songcha.module_bookreader.BuildConfig;
import com.songcha.module_bookreader.manager.SettingManager;
import com.songcha.module_bookreader.utils.LogUtils;
import com.songcha.library_common.util.ScreenUtil;
import com.songcha.library_common.util.TimeUtil;
import com.songcha.library_common.util.ToastUtil;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

import static java.lang.Math.abs;

/***
 * 处理抽象的点击，滑动事件
 */
public abstract class BaseReadView extends FrameLayout {

    public interface IOnReadStateChangeListener {

        void onChapterChanged(int chapter);

        void onPageChanged(int chapter, int page);

        void onLoadChapterFailure(int chapter,boolean isFromUser,int beginPos,int endPos);

        void onCenterClick();

        void onFlip();
    }

    public interface IOnChapterAdvertListener{
        boolean isShowChapterAdvert();
        void getChapterAdvertView(int curChapter,IOnGetChapterAdvertView listener);
        void onShowChapterAdvert();
        void onHideChapterAdvert();
        void onChapterAdvertCountDown(int countdown);
    }

    protected int mCanvasWidth;
    protected int mCanvasHeight;

    //down坐标
    protected float mLastDownX, mLastDownY;
    //move坐标
    protected PointF mTouch = new PointF();
    protected float mTouchDeltaX = 0; // 当前触摸点与按下时的点的差值

    protected Bitmap mCurPageBitmap, mNextPageBitmap;
    protected Canvas mCurrentPageCanvas, mNextPageCanvas;
    protected ReadPageFactory pageFactory = null;

    protected BaseReadView.IOnReadStateChangeListener mReadStateChangeListener;
    protected BaseReadView.IOnChapterAdvertListener mChapterAdvertListener;
    protected String bookId;
    public boolean isPrepared = false;

    Scroller mScroller;

    protected final static int START_ANIMATION_TIME = 300;
    protected final static int CANCEL_ANIMATION_TIME = 300;

    //private boolean mIsOnDrawWord=false;
    private IOnWordListener mOnWordListener;
    //private boolean mFontPath=false;

    private long mNoPageTipTime = 0L;

    private boolean mIsShowChapterAdvert = false;

    public void setOnWordListener(IOnWordListener listener){
        mOnWordListener = listener;
        pageFactory.setOnWordListener(mOnWordListener);
    }

    public void setIsOnDrawWord(boolean drawWord){
       // mIsOnDrawWord=drawWord;
        pageFactory.setIsOnDrawWord(drawWord);
    }

    public void setFontPath(String fontPath){
        pageFactory.setFontPath(fontPath);
    }

    public void setMarginTop(int marginTop){
       pageFactory.setMarginTop(marginTop);
    }
    //public ReadPageFactory getPageFactory(){
        //return pageFactory;
   // }

    public interface IOnWordListener{
        boolean isMarkWord(String word);
        void onWordClick(String word);
    }

    public interface IOnGetChapterAdvertView{
        void onSuccess(View view);
        void onFailed();
    }

    private int mScaledTouchSlop = 0;

    public BaseReadView(Context context, int width,int height,String bookId,
                        IOnReadStateChangeListener readStateChangeListener,
                        boolean isOnDrawWord,String fontPath, boolean isFromSD,
                        boolean isChapterAdvertPreLoadEnabled,
                        IOnChapterAdvertListener chapterAdvertListener) {
        super(context);

        setWillNotDraw(false);

        mIsShowChapterAdvert = chapterAdvertListener.isShowChapterAdvert();
        //TODO
        //mIsShowChapterAdvert = false;

        mIsChapterAdvertPreLoadEnabled = isChapterAdvertPreLoadEnabled;

       // mIsOnDrawWord=isOnDrawWord;
       // mFontPath=fontPath;

        this.bookId = bookId;
        this.mReadStateChangeListener = readStateChangeListener;
        this.mChapterAdvertListener = chapterAdvertListener;

        mCanvasWidth = width;
        mCanvasHeight = height;

        mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

        mCurPageBitmap = Bitmap.createBitmap(mCanvasWidth, mCanvasHeight, Bitmap.Config.ARGB_8888);
        mNextPageBitmap = Bitmap.createBitmap(mCanvasWidth, mCanvasHeight, Bitmap.Config.ARGB_8888);
        //autosize cannot auto set canvas density,so need to set manually
        mCurrentPageCanvas = new Canvas(mCurPageBitmap);
        mCurrentPageCanvas.setDensity(ScreenUtil.getDensityDpi());
        mNextPageCanvas = new Canvas(mNextPageBitmap);
        mNextPageCanvas.setDensity(ScreenUtil.getDensityDpi());

        mScroller = new Scroller(getContext());

        pageFactory = new ReadPageFactory(getContext(),ScreenUtil.getScreenWidth(), mCanvasHeight,
                SettingManager.getInstance().getReadFontSize(), bookId,isOnDrawWord,mOnWordListener,fontPath,
                isFromSD,
                mCurrentPageCanvas,mNextPageCanvas);
        pageFactory.setOnReadStateChangeListener(mReadStateChangeListener);

    }

    public void setCanvasHeight(int height){
        mCanvasHeight = height;
        //mCurPageBitmap = Bitmap.createBitmap(mCanvasWidth, mCanvasHeight, Bitmap.Config.ARGB_8888);
        //mNextPageBitmap = Bitmap.createBitmap(mCanvasWidth, mCanvasHeight, Bitmap.Config.ARGB_8888);
        //setBitmaps(mCurPageBitmap,mNextPageBitmap);
    }

    public void setChapterList(List<String> chaptersList){
        pageFactory.setChapterList(chaptersList);
    }

/*    public void jumpToPageLast(){
        pageFactory.pageLast();
    }*/

    public void pageToLast(){
        pageFactory.pageToLast();
    }

    /***
     * 是否正在翻页
     * @return
     */
    protected boolean isFlipping(){
        return !mScroller.isFinished() || maxDeltaX != 0f;
    }

    public void onLoadSuccess(){
        pageFactory.drawCanvas(mNextPageCanvas, ReadPageFactory.ReaderLoadState.LOAD_SUCCESS,false);
        //动画或滑动中不设置currentBitmap
        mPendingCurCanvasState = ReadPageFactory.ReaderLoadState.LOAD_SUCCESS;
        if(!isFlipping()){
            pageFactory.drawCanvas(mCurrentPageCanvas,  ReadPageFactory.ReaderLoadState.LOAD_SUCCESS,false);
        }else{

        }
    }

    public void onLoadError(){
        pageFactory.drawCanvas(mNextPageCanvas,  ReadPageFactory.ReaderLoadState.LOAD_ERROR,false);
        mPendingCurCanvasState = ReadPageFactory.ReaderLoadState.LOAD_ERROR;
        if(!isFlipping()){
            pageFactory.drawCanvas(mCurrentPageCanvas,  ReadPageFactory.ReaderLoadState.LOAD_ERROR,false);
        }else{

        }
    }

    public synchronized void init(Bitmap bgBitmap,int[] progress) {
        if(isPrepared) return;

        try {
            pageFactory.setBgBitmap(bgBitmap);
            // 自动跳转到上次阅读位置
            //int pos[] = SettingManager.getInstance().getReadProgress(bookId);
            //int pos[]={0,0,0};
            int ret = pageFactory.openBook(progress[0], new int[]{progress[1], progress[2]});
            //LogUtils.i("上次阅读位置：chapter=" + progress[0] + " beginPos=" + progress[1] + " endPos=" + progress[2]);
            if (ret == 0) {
                mReadStateChangeListener.onLoadChapterFailure(progress[0],true,progress[1],progress[2]);
                isPrepared = true;
                preLoadChapterAdvert();
                return;
            }

            if(progress[1] > 0){
                pageFactory.initCurrentPage(progress[1]);
            }

            pageFactory.drawCanvas(mCurrentPageCanvas,  ReadPageFactory.ReaderLoadState.LOAD_SUCCESS,false);
            postInvalidate();

            preLoadChapterAdvert();

        } catch (Exception e) {
            e.printStackTrace();
        }
        isPrepared = true;
    }

    public enum FlipDirection{
        NONE,
       //向右翻页
        RIGHT,
       //向左翻页
        LEFT,
        //向上翻页
        UP,
        //向下翻页
        DOWN
    }

    //临时变量
    private int dx, dy;
    private boolean isCancel = false;
    private boolean isCenter = false;
    private boolean isFlip = false;
    private boolean isNoPage = false;
    private FlipDirection flipDirection = FlipDirection.NONE;
    private float maxDeltaX = 0f;
    //只有翻页时为true,取消翻页时为false
    protected boolean mIsStartTrueFlipAnimation = false;
    private ReadPageFactory.ReaderLoadState mPendingCurCanvasState = ReadPageFactory.ReaderLoadState.LOAD_SUCCESS;


    /***
     * 核心代码
     * @param e The motion event.
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                return handleActionDown(e.getX(),e.getY());
            case MotionEvent.ACTION_MOVE:
                return handleActionMove(e.getX(),e.getY());
            case MotionEvent.ACTION_UP:
                handleActionUp(true);
                break;
            case MotionEvent.ACTION_CANCEL:
                handleActionCancel();
                break;
            default:
                break;
        }
        return true;
    }

    protected void setTouchDown(float x, float y){
        dx = (int)x;
        dy = (int)y;
        mLastDownX = dx;
        mLastDownY = dy;
        mTouch.x = dx;
        mTouch.y = dy;
        mTouchDeltaX = 0;
    }

    private int mChapterLastAdvertCountDown = 0;

    public boolean handleActionDown(float x,float y){
        //必须，画当前页面，否则可能为下一个页面
        //当前内容已经为下一页内容，所以调用ondraw可设置为下一页的bitmap
        //pageFactory.onDraw(mCurrentPageCanvas, ReadPageFactory.DrawType.ALL);

        if(mIsShowChapterLastAdvertCountDown && pageFactory.getCurCanvasIsDrawAdvert() && mChapterLastAdvertCountDown > 0){
            return false;
        }
        /*if(!b){
            setTouchDown(e);
            return true;
        }*/

        //点击中间,不翻页
        if (!pageFactory.getCurCanvasIsDrawAdvert() && x >= mCanvasWidth / 3 && x <= mCanvasWidth * 2 / 3
                && y >= mCanvasHeight / 3 && y <= mCanvasHeight * 2 / 3) {
            isCenter = true;

            if(!mScroller.isFinished()){
                return false;
            }
            setTouchDown(x,y);
        } else {
            isCenter = false;

            //先停止上次翻页，以免影响到当前翻页
            //abortAnimation();
            //postInvalidate();
            //画canvas会改变bitmap，因为canvas是依赖于bitmap

            if(!mScroller.isFinished()){
                return false;
            }
            //loading或error时禁止翻页
            ReadPageFactory.ReaderLoadState loadState = pageFactory.getCurCanvasLoadState();
            if(loadState == ReadPageFactory.ReaderLoadState.LOADING || loadState == ReadPageFactory.ReaderLoadState.LOAD_ERROR){
                return false;
            }
            setTouchDown(x,y);
            mIsStartTrueFlipAnimation = false;
        }
        return true;
    }

    public boolean handleActionMove(float x,float y){
        //if(isCenter) return true;
        //onAnimationUpdate(flipDirection);
        if(mIsShowChapterLastAdvertCountDown && pageFactory.getCurCanvasIsDrawAdvert() && mChapterLastAdvertCountDown > 0){
            return false;
        }

        float deltaX = x - mLastDownX;

        //判断是否响应滑动操作
        if(abs(deltaX) < mScaledTouchSlop) return true;

        isCenter = false;

        //获取最大滑动x位移
        if(flipDirection == FlipDirection.RIGHT){
            if(maxDeltaX == 0 || x < maxDeltaX){
                maxDeltaX = x;
            }
        }else if(flipDirection == FlipDirection.LEFT){
            if(maxDeltaX == 0 || x > maxDeltaX){
                maxDeltaX = x;
            }
        }

        //未翻页
        if(!isFlip){
            mIsStartTrueFlipAnimation = false;
            //pageFactory.drawCanvas(mCurrentPageCanvas, ReadPageFactory.DrawType.ALL, null);

            if(deltaX < 0){
                boolean isNoPage = handleFlipRight();
                if(isNoPage) return false;
            }else if(deltaX > 0){
                boolean isNoPage = handleFlipLeft();
                if(isNoPage) return false;
            }
            mReadStateChangeListener.onFlip();
            setBitmaps(mCurPageBitmap, mNextPageBitmap);
            isFlip = true;
        }else{
            //翻页中
            if(isNoPage) return true;
            if(flipDirection == FlipDirection.NONE) return true;
            onAnimationUpdate(flipDirection);
            mTouch.x = x;
            mTouch.y = y;
            mTouchDeltaX = mTouch.x - mLastDownX;
            postInvalidate();
        }
        return true;
    }

    public void handleActionUp(boolean isFlipEnabled){
        /*if(mIsShowChapterLastAdvertCountDown && pageFactory.getCurCanvasIsDrawAdvert() && mChapterLastAdvertCountDown > 0){
            return;
        }*/
        //点击中间
        if (isCenter) {
            mReadStateChangeListener.onCenterClick();
            resetTouchPoint();
            postInvalidate();
        }else{
            if (isCancel) {
                //取消动画，防止异常情况的判断
               cancelFlip();
            } else if(isNoPage){
                //没有页面
                resetTouchPoint();
                postInvalidate();
            } else {
                //不翻页则判断是否应该翻页,翻页则开始动画
                if(!isFlip){
                    if(isFlipEnabled){
                        //处理非用户操作的自动跳转
                        if(mLastDownX > 0 && mLastDownX < mCanvasWidth / 3){
                            boolean isNoPage = handleFlipLeft();
                            if(isNoPage)
                                return;
                            else
                                isFlip = true;
                        }else if(mLastDownX > mCanvasWidth / 3 * 2 && mLastDownX < mCanvasWidth){
                            boolean isNoPage = handleFlipRight();
                            if(isNoPage)
                                return;
                            else
                                isFlip = true;
                        }
                        if(isFlip){
                            startTrueFlipPage();
                        }
                    }else{
                        //cancelFlip();
                        resetTouchPoint();
                        postInvalidate();
                    }
                }else{
                    //翻页
                    //判断是否取消翻页
                    //如果滑动距离小于最大距离，则视为取消
                    if(flipDirection == FlipDirection.RIGHT){
                        if(mTouch.x > maxDeltaX){
                            isCancel = true;
                        }
                    }else if(flipDirection == FlipDirection.LEFT){
                        if(mTouch.x < maxDeltaX){
                            isCancel = true;
                        }
                    }
                    if(isCancel){
                        cancelFlip();
                    }else{
                        startTrueFlipPage();
                    }

                }

            }
        }

        clearTouchState();

    }

    private int getContinuousFlipSameDirectionCount(FlipDirection flipDirection){
        int ret = mContinuousFlipSameDirectionCount;
        if(flipDirection == FlipDirection.RIGHT){
            if(mLastFlipDirection == FlipDirection.RIGHT){
                ret++;
            }else{
                ret = 1;
            }
        }else if(flipDirection == FlipDirection.LEFT){
            if(mLastFlipDirection == FlipDirection.LEFT){
                ret++;
            }else{
                ret = 1;
            }
        }
        if(mIsDrawAdvert){
            ret = 0;
        }

        return ret;
    }

    private void startTrueFlipPage(){
        if(flipDirection == FlipDirection.NONE) return;

        mContinuousFlipSameDirectionCount = getContinuousFlipSameDirectionCount(flipDirection);

        if(mIsDrawAdvert){
            mDiffChapterAdvertPage = 0;
            mChapterAdvertThreshold = 8 + new Random().nextInt(3);
        }else{
            if(flipDirection == FlipDirection.RIGHT){
                mDiffChapterAdvertPage++;
            }else if(flipDirection == FlipDirection.LEFT){
                mDiffChapterAdvertPage--;
            }
        }

        //LogUtils.d("aaa,"+flipDirection+","+mContinuousFlipSameDirectionCount+","+mDiffChapterAdvertPage);
        //LogUtils.d("aaa1",pageFactory.getCurChapter()+","+pageFactory.getCurrentPage());

        mLastFlipDirection = flipDirection;

        mReadStateChangeListener.onFlip();
        setBitmaps(mCurPageBitmap, mNextPageBitmap);
        mIsStartTrueFlipAnimation = true;
        startAnimation(flipDirection);
        postInvalidate();
    }

    private void cancelFlip(){
        if(flipDirection == FlipDirection.NONE) return;

        if(!mIsShowChapterAdvert){
            pageFactory.cancelPage(flipDirection,false);
        }else{
            if(pageFactory.getCurCanvasIsDrawAdvert()){
                if(!mIsDrawAdvert){
                    mIsDrawAdvert = true;
                }
                mChapterAdvertListener.onShowChapterAdvert();
            }else{
                if(mIsDrawAdvert){
                    mIsDrawAdvert = false;
                }
                mChapterAdvertListener.onHideChapterAdvert();
                if(flipDirection == FlipDirection.RIGHT){
                    if(!pageFactory.isLastPage() || pageFactory.getCurChapter() == pageFactory.getChapterSize())
                        pageFactory.cancelPage(flipDirection,false);
                }else if(flipDirection == FlipDirection.LEFT){
                    if(!pageFactory.isFirstPage() || pageFactory.getCurChapter() == 1)
                        pageFactory.cancelPage(flipDirection,false);
                }
            }
        }

        restoreAnimation(flipDirection);
        postInvalidate();
    }

    public void handleActionCancel(){
        resetFlipDirection();
        resetTouchPoint();
        postInvalidate();
        clearTouchState();
    }

    public boolean isChapterLastAdvertShowing(){
        return mChapterAdvertView != null && mChapterAdvertView.getVisibility() == View.VISIBLE && pageFactory.getCurCanvasIsDrawAdvert();
    }

    private boolean mIsDrawAdvert = false;
    private FlipDirection mLastFlipDirection = FlipDirection.NONE;
    //连续同方向翻页的页数
    private int mContinuousFlipSameDirectionCount = 0;
    //当前距离广告的页数
    private int mDiffChapterAdvertPage = -1;
    //翻页触发章节广告页数
    private int mChapterAdvertThreshold = 8 + new Random().nextInt(3);

    /***
     * 上一页翻页
     * @return
     */
    private boolean handleFlipLeft(){
        flipDirection = FlipDirection.LEFT;
        calcCornerXY(mLastDownX, mLastDownY,flipDirection);

        /*if(mLastChapterFlipDirection == FlipDirection.LEFT){
            mContinuousFlipSameDirectionCount++;
        }else{
            mContinuousFlipSameDirectionCount = 1;
        }*/

        //LogUtils.d("aaa left",mContinuousFlipSameDirectionCount);

        //mLastFlipDirection = FlipDirection.LEFT;

        if(mIsShowChapterAdvert){
            if(isShowChapterAdvertWhenFlip(flipDirection)){
                mIsDrawAdvert = true;
                pageFactory.drawCanvas(mNextPageCanvas, null,true);
                return false;
            }else{
                //来回翻页取消时不应该读取上一页
                if(isShowChapterAdvertWhenFlipTurn(flipDirection)){
                    mIsDrawAdvert = false;
                    pageFactory.drawCanvas(mNextPageCanvas, null,false);
                    return false;
                }
                mIsDrawAdvert = false;
            }
        }

        BookStatus status = pageFactory.prePage(true);
        if (status == BookStatus.NO_PRE_PAGE) {
            handleNoPrePageToast();
            resetTouchPoint();
            postInvalidate();
            isNoPage = true;
            //isFlip=true;
            resetFlipDirection();
            return true;
        } else if (status == BookStatus.LOAD_SUCCESS) {
            pageFactory.drawCanvas(mNextPageCanvas, ReadPageFactory.ReaderLoadState.LOAD_SUCCESS,false);
        } else {
            //设置加载中状态
            mPendingCurCanvasState = ReadPageFactory.ReaderLoadState.LOADING;
            pageFactory.drawCanvas(mNextPageCanvas, ReadPageFactory.ReaderLoadState.LOADING,false);
        }
        return false;
    }

    /***
     * 下一页翻页
     * @return
     */
    private boolean handleFlipRight(){
        flipDirection = FlipDirection.RIGHT;
        calcCornerXY(mLastDownX, mLastDownY,flipDirection);

        /*if(mLastChapterFlipDirection == FlipDirection.RIGHT){
            mContinuousFlipSameDirectionCount++;
        }else{
            mContinuousFlipSameDirectionCount = 1;
        }*/

        //LogUtils.d("aaa right",mContinuousFlipSameDirectionCount);

        //mLastFlipDirection = FlipDirection.RIGHT;

        if(mIsShowChapterAdvert){
            if(isShowChapterAdvertWhenFlip(flipDirection)){
                mIsDrawAdvert = true;
                pageFactory.drawCanvas(mNextPageCanvas,null,true);
                return false;
            }else{
                //来回翻页取消时不应该读取下一页
                if(isShowChapterAdvertWhenFlipTurn(flipDirection)){
                    mIsDrawAdvert = false;
                    pageFactory.drawCanvas(mNextPageCanvas, null,false);
                    return false;
                }
                mIsDrawAdvert = false;
            }
        }

        BookStatus status = pageFactory.nextPage(true);
        if (status == BookStatus.NO_NEXT_PAGE) {
            handleNoNextPageToast();
            resetTouchPoint();
            postInvalidate();
            isNoPage = true;
            resetFlipDirection();
            return true;
        } else if (status == BookStatus.LOAD_SUCCESS) {
            pageFactory.drawCanvas(mNextPageCanvas, ReadPageFactory.ReaderLoadState.LOAD_SUCCESS,false);
        } else {
            //设置加载中状态
            mPendingCurCanvasState = ReadPageFactory.ReaderLoadState.LOADING;
            pageFactory.drawCanvas(mNextPageCanvas, ReadPageFactory.ReaderLoadState.LOADING,false);
        }
        return false;
    }


    //显示广告时页数不变，只是在上面盖了一层
    private boolean isShowChapterAdvertWhenFlip(FlipDirection flipDirection){
       /* if(flipDirection == FlipDirection.RIGHT){
            return !mIsDrawAdvert && pageFactory.isLastPage() && pageFactory.getCurChapter() < pageFactory.getChapterSize();
        }else if(flipDirection == FlipDirection.LEFT){
            return !mIsDrawAdvert && !pageFactory.getCurCanvasIsDrawAdvert() && pageFactory.isFirstPage() && pageFactory.getCurChapter() > 1;
        }else{
            return false;
        }*/

        if(flipDirection == FlipDirection.RIGHT){
            return (!mIsDrawAdvert && getContinuousFlipSameDirectionCount(FlipDirection.RIGHT) == mChapterAdvertThreshold) ||
                    (mChapterAdvertView != null && mDiffChapterAdvertPage + 1 == 0) &&
                    !(pageFactory.getCurChapter() == pageFactory.getChapterSize() && pageFactory.isLastPage());
        }else if(flipDirection == FlipDirection.LEFT){
            return (!mIsDrawAdvert && getContinuousFlipSameDirectionCount(FlipDirection.LEFT) == mChapterAdvertThreshold) ||
                    (mChapterAdvertView != null && mDiffChapterAdvertPage - 1 == 0) &&
                            !(pageFactory.getCurChapter() == 1 && pageFactory.isFirstPage());
        }else{
            return false;
        }
    }

    //TODO
    private boolean isShowChapterAdvertWhenFlipTurn(FlipDirection flipDirection){
        /*if(flipDirection == FlipDirection.RIGHT){
            return mIsDrawAdvert && pageFactory.isFirstPage();
        }else if(flipDirection == FlipDirection.LEFT){
            return mIsDrawAdvert && pageFactory.isLastPage();
        }else{
            return false;
        }*/

        if(flipDirection == FlipDirection.RIGHT){
            return mIsDrawAdvert && mLastFlipDirection == FlipDirection.LEFT;
        }else if(flipDirection == FlipDirection.LEFT){
            return mIsDrawAdvert && mLastFlipDirection == FlipDirection.RIGHT;
        }else{
            return false;
        }

    }

    //TODO
    private boolean isRemoveChapterAdvertView(FlipDirection flipDirection){
        /*if(flipDirection == FlipDirection.RIGHT){
            return pageFactory.getCurrentPage() > 1;
        }else if(flipDirection == FlipDirection.LEFT){
            return !pageFactory.isLastPage();
        }
        return false;*/

        if(flipDirection == FlipDirection.RIGHT){
            return mDiffChapterAdvertPage > 1;
        }else if(flipDirection == FlipDirection.LEFT){
            return mDiffChapterAdvertPage < -1;
        }
        return false;
    }

    private View mChapterAdvertView;
    private final static int CHAPTER_ADVERT_COUNT_DOWN_SECOND = 5;
    private Disposable mChapterLastAdvertCountDownDispose;
    //TODO
    private boolean mIsShowChapterLastAdvertCountDown = true;

    public boolean isShowChapterLastAdvertCountDown(){
        return mIsShowChapterLastAdvertCountDown;
    }

    public int get_CHAPTER_ADVERT_COUNT_DOWN_SECOND(){
        return CHAPTER_ADVERT_COUNT_DOWN_SECOND;
    }

    private void getChapterAdvertView(IOnGetChapterAdvertView listener){
        //TODO
        mChapterAdvertListener.getChapterAdvertView(pageFactory.getCurChapter(),listener);

        //returnRandomChapterAdvertView(listener);
    }

    private void returnRandomChapterAdvertView(IOnGetChapterAdvertView listener){
        FrameLayout fl = new FrameLayout(getContext());
        fl.setBackgroundColor(Color.RED);
        LayoutParams flLp = new LayoutParams(ScreenUtil.getScreenWidth(),400);
        flLp.gravity = Gravity.CENTER;
        fl.setLayoutParams(flLp);

        TextView tv = new TextView(getContext());
        tv.setTextSize(14);
        tv.setTextColor(Color.BLACK);
        int rand = new Random().nextInt(100) + 1;
        tv.setText(rand + "");
        LayoutParams tvLp = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        tvLp.gravity = Gravity.CENTER;
        tv.setLayoutParams(tvLp);

        fl.addView(tv);
        listener.onSuccess(fl);
    }

    private View mTmpChapterAdvertView;
    private boolean mIsChapterAdvertPreLoadEnabled = false;

    private void preLoadChapterAdvert(){
        if(!mIsChapterAdvertPreLoadEnabled) return;
        if(!mIsShowChapterAdvert || mChapterAdvertView != null || mTmpChapterAdvertView != null) return;
        getChapterAdvertView(new IOnGetChapterAdvertView() {
            @Override
            public void onSuccess(View view) {
                mTmpChapterAdvertView = view;
            }

            @Override
            public void onFailed() {

            }
        });
    }

    private void initChapterLastAdvertCountDownDispose(){
        if(mIsShowChapterLastAdvertCountDown){
            mChapterLastAdvertCountDown = CHAPTER_ADVERT_COUNT_DOWN_SECOND;

            if(mChapterLastAdvertCountDownDispose != null)
                mChapterLastAdvertCountDownDispose.dispose();

            mChapterLastAdvertCountDownDispose = Observable.intervalRange(0,CHAPTER_ADVERT_COUNT_DOWN_SECOND + 1,0,1, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.computation())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long value) throws Exception {
                            mChapterLastAdvertCountDown = CHAPTER_ADVERT_COUNT_DOWN_SECOND - value.intValue();
                            //TODO
                            mChapterAdvertListener.onChapterAdvertCountDown(mChapterLastAdvertCountDown);
                            //pageFactory.drawPageLastAdvertCountDown(mChapterLastAdvertCountDown);
                            //postInvalidate();
                        }
                    });
        }
    }

    private void addChapterLastAdvertView(IOnGetChapterAdvertView listener){
        removeAllViews();

        initChapterLastAdvertCountDownDispose();

        if(mTmpChapterAdvertView != null){
            mChapterAdvertView = mTmpChapterAdvertView;
            addView(mChapterAdvertView);

            listener.onSuccess(mChapterAdvertView);
            mTmpChapterAdvertView = null;
            return;
        }

        getChapterAdvertView(new IOnGetChapterAdvertView() {
            @Override
            public void onSuccess(View view) {
                if(!mIsDrawAdvert) return;
                mChapterAdvertView = view;
                addView(mChapterAdvertView);
                listener.onSuccess(mChapterAdvertView);
            }

            @Override
            public void onFailed() {
                if(!mIsDrawAdvert) return;
                clearChapterLastAdvertCountDownDispose();
                listener.onFailed();
            }
        });

    }

    private void clearChapterLastAdvertCountDownDispose(){
        if(mChapterLastAdvertCountDownDispose != null)
            mChapterLastAdvertCountDownDispose.dispose();
        mChapterLastAdvertCountDown = 0;
        mChapterAdvertListener.onChapterAdvertCountDown(mChapterLastAdvertCountDown);
    }

    private void removeChapterAdvertView(){
        removeAllViews();
        mChapterAdvertView = null;
        mTmpChapterAdvertView = null;
        clearChapterLastAdvertCountDownDispose();
    }

    private void handleNoPrePageToast(){
        if(!BuildConfig.DEBUG && (TimeUtil.getCurrentTimeSecond() - mNoPageTipTime < 60000)) return;
        ToastUtil.show("没有上一页啦",null);
        mNoPageTipTime = TimeUtil.getCurrentTime();

    }

    private void handleNoNextPageToast(){
        if(!BuildConfig.DEBUG && (TimeUtil.getCurrentTimeSecond() - mNoPageTipTime < 60000)) return;
        ToastUtil.show("没有下一页啦",null);
        mNoPageTipTime = TimeUtil.getCurrentTime();

    }

    protected void clearTouchState(){
        isCenter = false;
        isCancel = false;
        isFlip = false;
        isNoPage = false;
        resetFlipDirection();
        mTouch.x = 0;
        mTouch.y = 0;
        maxDeltaX = 0f;
        //mTouchDeltaX = 0;
    }

    /*private void clearTouchPoint(){
        mTouchDeltaX = 0;
        mTouch.x = 0;
        mTouch.y = 0;
    }*/

    private void resetFlipDirection(){
        flipDirection = FlipDirection.NONE;
    }

    @Override
    public void computeScroll() {
        //真正翻页结束且动画完成后更新curBitmap为nextBitmap，否则下次绘制会错乱
        if (mIsStartTrueFlipAnimation && mScroller.isFinished()) {
            resetTouchPoint();
            resetFlipDirection();

            mIsStartTrueFlipAnimation = false;

            if(mPendingCurCanvasState == ReadPageFactory.ReaderLoadState.LOADING){
                pageFactory.drawCanvas(mCurrentPageCanvas, ReadPageFactory.ReaderLoadState.LOADING,false);
                //resetFlipDirection();
            }else if(mPendingCurCanvasState == ReadPageFactory.ReaderLoadState.LOAD_ERROR){
                pageFactory.drawCanvas(mCurrentPageCanvas, ReadPageFactory.ReaderLoadState.LOAD_ERROR,false);
                //resetFlipDirection();
            }else{
                handleScrollFinishedChapterAdvert();
                pageFactory.drawCanvas(mCurrentPageCanvas, ReadPageFactory.ReaderLoadState.LOAD_SUCCESS,mIsDrawAdvert);
            }
            setBitmaps(mCurPageBitmap,mNextPageBitmap);
            //postInvalidate();
        }
    }

    //加载失败或手动关闭时跳过广告
    public void skipPageLastAdvert(){
        if(mLastFlipDirection == FlipDirection.NONE) return;
        if(mChapterLastAdvertCountDown > 0) return;
        
        mChapterAdvertListener.onHideChapterAdvert();
        if(mLastFlipDirection == FlipDirection.RIGHT){
            handleFlipRight();
        }else if(mLastFlipDirection == FlipDirection.LEFT){
            handleFlipLeft();
        }
        mReadStateChangeListener.onFlip();
        setBitmaps(mCurPageBitmap, mNextPageBitmap);
        mIsStartTrueFlipAnimation = true;
        postInvalidate();
        //resetFlipDirection();
        //mLastChapterFlipDirection = FlipDirection.NONE;
        removeChapterAdvertView();
    }

    //广告显示处理
    private void handleScrollFinishedChapterAdvert(){
        if(!mIsShowChapterAdvert) return;

        //LogUtils.d("handleScrollFinishedPageAdvert",mLastChapterFlipDirection);


        if(mIsDrawAdvert){
            //显示广告
            if(mChapterAdvertView == null){
                 mChapterAdvertListener.onShowChapterAdvert();

                 addChapterLastAdvertView(new IOnGetChapterAdvertView() {
                    @Override
                    public void onSuccess(View view) {
                        //resetFlipDirection();
                    }

                    @Override
                    public void onFailed() {
                        //广告加载失败时处理
                        skipPageLastAdvert();
                        //resetFlipDirection();
                    }
                });
            }else{
                //resetFlipDirection();
                //显示缓存广告
                if(mChapterAdvertView.getVisibility() == View.VISIBLE){
                    ViewHelper.setVisibility(false,mChapterAdvertView);
                    mChapterAdvertListener.onHideChapterAdvert();
                } else{
                    //TODO 部分广告无效，原因未知
                    ViewHelper.setVisibility(true,mChapterAdvertView);
                    mChapterAdvertListener.onShowChapterAdvert();
                }
            }
        }else{
            //隐藏或移除广告
            if(mChapterAdvertView != null){
                if(isRemoveChapterAdvertView(mLastFlipDirection)){
                    removeChapterAdvertView();
                }else{
                    ViewHelper.setVisibility(false,mChapterAdvertView);
                }
                mChapterAdvertListener.onHideChapterAdvert();
            }else{
                //广告预加载
                if(isPreLoadChapterAdvert()) {
                    preLoadChapterAdvert();
                }
            }
        }
    }

    private boolean isPreLoadChapterAdvert(){
         /*if((pageFactory.isLastPage() && pageFactory.getCurrentPage() < pageFactory.getChapterSize())
                        || (pageFactory.isFirstPage() && pageFactory.getCurrentPage() == 1)
                )*/
        return (mIsChapterAdvertPreLoadEnabled && (pageFactory.getCurrentPage() < pageFactory.getChapterSize()
                || pageFactory.getCurrentPage() == 1));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        calcPoints();
        drawCurrentPageArea(canvas);
        drawNextPageAreaAndShadow(canvas);
        drawCurrentPageShadow(canvas);
        drawCurrentBackArea(canvas);

        if(mIsShowChapterAdvert && mChapterAdvertView != null){
            //LogUtils.d("aaa",mTouchDeltaX);
            drawChapterLastAdvertViewAnimation(canvas,mChapterAdvertView);
        }
    }

    protected void drawChapterLastAdvertViewAnimation(Canvas canvas,View adView){}

    protected abstract void drawNextPageAreaAndShadow(Canvas canvas);

    protected abstract void drawCurrentPageShadow(Canvas canvas);

    protected abstract void drawCurrentBackArea(Canvas canvas);

    protected abstract void drawCurrentPageArea(Canvas canvas);

    protected abstract void calcPoints();

    //用于3d翻页计算折角坐标
    protected abstract void calcCornerXY(float x, float y,FlipDirection direction);

    /**
     * 开启翻页动画，无论是否翻页都会显示动画
     */
    protected abstract void startAnimation(FlipDirection direction);

    /**
     * 停止翻页动画（滑到一半调用停止的话  翻页效果会卡住 可调用#{restoreAnimation} 还原效果）
     */
    protected abstract void abortAnimation();

    /**
     * 还原翻页
     */
    protected abstract void restoreAnimation(FlipDirection direction);

    /***
     * 动画更新
     */
    protected abstract void onAnimationUpdate(FlipDirection direction);

    //需要调用该方法更新bitmap
    protected abstract void setBitmaps(Bitmap mCurPageBitmap, Bitmap mNextPageBitmap);

    public abstract void setTheme(int theme);

    public void setBackgroundBitmap(Bitmap bitmap){
        if (bitmap != null) {
            pageFactory.setBgBitmap(bitmap);
            if (isPrepared) {
                pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
                pageFactory.drawCanvas(mNextPageCanvas,null,false);
                postInvalidate();
            }
        }
    }

    /**
     *
     * 复位触摸点位
     */
    protected void resetTouchPoint() {
        //坑：该代码导致3d翻页bug
      /*  mTouch.x = 0.1f;
        mTouch.y = 0.1f;*/
        mTouch.x = 0f;
        mTouch.y = 0f;
        mTouchDeltaX = 0f;
        calcCornerXY(mTouch.x, mTouch.y,FlipDirection.NONE);
    }

    public void jumpToChapter(int chapter,boolean isFromUser,int beginPos,int endPos) {//boolean isOnChapterChange
        //目前只有init()需要跳转pos
        if(endPos > 0 && endPos <= beginPos) return;
        //resetTouchPoint();
        int ret = pageFactory.openBook(chapter, new int[]{beginPos, endPos});
        if(ret == 0){
            pageFactory.onLoadChapterFailure(chapter,isFromUser,0,0);
        }
        pageFactory.drawCanvas(mNextPageCanvas, null,false);
        if(!isFlipping()){
            pageFactory.drawCanvas(mCurrentPageCanvas,null,false);
        }else{
            mPendingCurCanvasState=ReadPageFactory.ReaderLoadState.LOAD_SUCCESS;
        }
        //removeChapterAdvertView();
        postInvalidate();
    }

    public void nextPage() {
        BookStatus status = pageFactory.nextPage(false);
        if (status == BookStatus.NO_NEXT_PAGE) {
            handleNoNextPageToast();
        } else if (status == BookStatus.LOAD_SUCCESS) {
            if (isPrepared) {
                pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
                pageFactory.drawCanvas(mNextPageCanvas, null,false);
                postInvalidate();
            }
        } else {

        }
    }

    public void prePage() {
        BookStatus status = pageFactory.prePage(false);
        if (status == BookStatus.NO_PRE_PAGE) {
            handleNoPrePageToast();
        } else if (status == BookStatus.LOAD_SUCCESS) {
            if (isPrepared) {
                pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
                pageFactory.drawCanvas(mNextPageCanvas,null,false);
                postInvalidate();
            }
        } else {
        }
    }

    public synchronized void setFontSize(final int sp) {
        resetTouchPoint();
        pageFactory.setTextFont(sp);
        if (isPrepared) {
            pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
            pageFactory.drawCanvas(mNextPageCanvas,null,false);
            //SettingManager.getInstance().saveFontSize(bookId, fontSizePx);
            //SettingManager.getInstance().saveFontSize(sp);
            postInvalidate();
        }
    }

    public synchronized void setLineSpaceRatio(int ratio) {
        resetTouchPoint();
        pageFactory.setLineSpaceRatio(ratio);
        if (isPrepared) {
            pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
            pageFactory.drawCanvas(mNextPageCanvas,null,false);
            //SettingManager.getInstance().saveFontSize(bookId, fontSizePx);
           // SettingManager.getInstance().saveFontSize(sp);
            postInvalidate();
        }
    }

    public int getCurrentBeginPos(){
        return pageFactory.getCurBeginPos();
    }

    public int getCurrentEndPos(){
        return pageFactory.getCurEndPos();
    }

    public int getBufferLength(){
        return pageFactory.getBufferLen();
    }


    public synchronized void setTextColor(int textColor, int titleColor) {
        resetTouchPoint();
        pageFactory.setTextColor(textColor, titleColor);
        if (isPrepared) {
            pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
            pageFactory.drawCanvas(mNextPageCanvas, null,false);
            postInvalidate();
        }
    }

    public void updateAll() {
        if (isPrepared) {
            pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
            pageFactory.drawCanvas(mNextPageCanvas, null,false);
            postInvalidate();
        }
    }

    //更新电量和时间有可能导致绘制错乱
    /***
     * 设置电量
     * @param battery
     */
    public void setBattery(int battery) {
        pageFactory.setBattery(battery);
        /*if (isPrepared && !isFlipping()) {
            pageFactory.drawCanvas(mCurrentPageCanvas, null);
            postInvalidate();
        }*/
    }

    public void setTime(String time) {
        pageFactory.setTime(time);
        //翻页中不更新
        /*if (isPrepared && !isFlipping()) {
            pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
            postInvalidate();
        }*/
    }

    public void setPosition(int[] pos) {
        int ret = pageFactory.openBook(pos[0], new int[]{pos[1], pos[2]});
        if (ret == 0) {
            mReadStateChangeListener.onLoadChapterFailure(pos[0],false,0,0);
            return;
        }
        pageFactory.drawCanvas(mCurrentPageCanvas, null,false);
        postInvalidate();
    }

    public int[] getReadPos() {
        return pageFactory.getPosition();
    }

    public String getHeadLine() {
        return pageFactory.getHeadLineStr().replaceAll("@", "");
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (pageFactory != null) {
            pageFactory.recycle();
        }

        if (mCurPageBitmap != null && !mCurPageBitmap.isRecycled()) {
            mCurPageBitmap.recycle();
            mCurPageBitmap = null;
            LogUtils.d("mCurPageBitmap recycle");
        }

        if (mNextPageBitmap != null && !mNextPageBitmap.isRecycled()) {
            mNextPageBitmap.recycle();
            mNextPageBitmap = null;
            LogUtils.d("mNextPageBitmap recycle");
        }
    }


}
